package com.pickup.netty.controller;


import com.pickup.aspect.WebLog;
import com.pickup.enums.MsgSignFlagEnum;
import com.pickup.kafka.consumer.KafkaConsumer;
import com.pickup.netty.annotations.SocketMapping;
import com.pickup.netty.enums.NettyRequestType;
import com.pickup.netty.enums.NettyResultType;
import com.pickup.netty.message.ChatMessage;
import com.pickup.netty.message.NettyData;
import com.pickup.netty.server.handler.ChatInboundHandler;
import com.pickup.netty.server.session.SessionFactory;

import com.pickup.pool.ThreadPoolUtil;
import com.pickup.rabbitMQ.consumer.RabbitMqConsumer;


import com.pickup.rabbitMQ.provider.RabbitMqProvider;
import com.pickup.service.impl.UserServiceImpl;
import com.pickup.utils.JsonUtils;
import com.pickup.utils.SpringUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.io.UnsupportedEncodingException;
import java.util.HashSet;

@Slf4j
public class SocketController {


    UserServiceImpl userService = (UserServiceImpl) SpringUtil.getBean("userServiceImpl");

    RabbitMqConsumer rabbitMqConsumer = (RabbitMqConsumer) SpringUtil.getBean("rabbitMqConsumer");

    RabbitMqProvider rabbitMqProvider = (RabbitMqProvider) SpringUtil.getBean("rabbitMqProvider");


    /**
     * 打开连接
     * 连接用户关系入concurrentHashMap
     */


    @Autowired
    private KafkaConsumer kafkaConsumer;

    // 连接websocket
    @SocketMapping(NettyRequestType.OpenWebsocket)
    public void openWebsocket(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        log.info("连接websocket");
        String senderId = nettyData.getChatMessage().getSenderId();
        SessionFactory.getSession().bind(nettyData.getChatMessage().getSenderId(), ctx.channel());
        HashSet<String> userSign = rabbitMqConsumer.consumerConfig("ChatMessage" + senderId.hashCode() % 2, senderId);
        ctx.channel().eventLoop().execute(() -> {
            for (String sign : userSign) {
                if (sign.equals("0")) {
                    ctx.channel().eventLoop().execute(() -> {
                        userService.getUnReadMsgList(senderId);
                    });
                }
                if (sign.equals("1")) {
                    ctx.channel().eventLoop().execute(() -> {
                        userService.getUnReadMsgGroupList(senderId);
                    });
                }
            }
        });
    }

    // 心跳连接
    @SocketMapping(NettyRequestType.KeepALive)
    public void keepALive(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //log.info("心跳连接");
        String senderId = nettyData.getChatMessage().getSenderId();
        SessionFactory.getSession().bind(nettyData.getChatMessage().getSenderId(), ctx.channel());

        HashSet<String> userSign = rabbitMqConsumer.consumerConfig("ChatMessage" + senderId.hashCode() % 2, senderId);
        ctx.channel().eventLoop().execute(() -> {
            for (String sign : userSign) {
                if (sign.equals("0")) {
                    ctx.channel().eventLoop().execute(() -> {
                        userService.getUnReadMsgList(senderId);
                    });
                }
                if (sign.equals("1")) {
                    ctx.channel().eventLoop().execute(() -> {
                        userService.getUnReadMsgGroupList(senderId);
                    });
                }
            }
        });
    }

    // 发送私聊消息
    @SocketMapping(NettyRequestType.SingleChatSendMsg)
    public void singleChatSendMsg(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("发送私聊消息: ");
        ChatMessage chatMsg = nettyData.getChatMessage();
        Channel channel = SessionFactory.getSession().getChannel(chatMsg.getReceiverId());
        ChannelGroup users = ChatInboundHandler.users;

        ctx.channel().eventLoop().execute(() -> {
            if (channel != null && users.find(channel.id()) != null) {
                String msgId = userService.saveMsg(chatMsg, MsgSignFlagEnum.signed.type);
                chatMsg.setMsgId(msgId);
                nettyData.setChatMessage(chatMsg);
                nettyData.setAction(NettyResultType.AcceptSingleChatMsg);
                channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
            } else {
                userService.saveMsg(chatMsg, MsgSignFlagEnum.unsign.type);
                rabbitMqProvider.sendMessage(chatMsg.getReceiverId(), chatMsg.getReceiverId() + ",0");
            }
        });
    }

    // 接收私聊图片
    @SocketMapping(NettyRequestType.SingleChatSendImage)
    public void singleChatSendImage(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) throws UnsupportedEncodingException {
        log.info("接收私聊图片");
        ChatMessage chatMsg = nettyData.getChatMessage();
        Channel channel = SessionFactory.getSession().getChannel(chatMsg.getReceiverId());
        ChannelGroup users = ChatInboundHandler.users;

        ctx.channel().eventLoop().execute(() -> {
            if (channel != null && users.find(channel.id()) != null) {
                String msgId = userService.saveMsg(chatMsg, MsgSignFlagEnum.signed.type);
                chatMsg.setMsgId(msgId);
                nettyData.setChatMessage(chatMsg);
                nettyData.setAction(NettyResultType.AcceptSingleChatImage);
                channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
            } else {
                userService.saveMsg(chatMsg, MsgSignFlagEnum.unsign.type);
                rabbitMqProvider.sendMessage(chatMsg.getReceiverId(), chatMsg.getReceiverId() + ",0");
            }
        });
    }

    // 接收私聊视频
    @SocketMapping(NettyRequestType.SingleChatSendVideo)
    public void singleChatSendVideo(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) throws UnsupportedEncodingException {
        log.info("接收私聊视频");
        ChatMessage chatMsg = nettyData.getChatMessage();
        Channel channel = SessionFactory.getSession().getChannel(chatMsg.getReceiverId());
        ChannelGroup users = ChatInboundHandler.users;

        ctx.channel().eventLoop().execute(() -> {
            if (channel != null && users.find(channel.id()) != null) {
                String msgId = userService.saveMsg(chatMsg, MsgSignFlagEnum.signed.type);
                chatMsg.setMsgId(msgId);
                nettyData.setChatMessage(chatMsg);
                nettyData.setAction(NettyResultType.AcceptSingleChatVideo);
                channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
            } else {
                userService.saveMsg(chatMsg, MsgSignFlagEnum.unsign.type);
                rabbitMqProvider.sendMessage(chatMsg.getReceiverId(), chatMsg.getReceiverId() + ",0");
            }
        });
    }


    // 发送群聊消息
    @SocketMapping(NettyRequestType.GroupChatSendMsg)
    public void groupChatMsg(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("发送群聊消息");
        String extend = nettyData.getExtend();
        String[] allGroupId = extend.split(",");
        ChannelGroup users = ChatInboundHandler.users;

        ctx.channel().eventLoop().execute(() -> {
            for (String userId : allGroupId) {
                Channel channel = SessionFactory.getSession().getChannel(userId);
                if (channel != null && users.find(channel.id()) != null) {
                    String msgId = userService.saveGroupMsg(nettyData.getChatMessage(), MsgSignFlagEnum.signed.type, userId);
                    nettyData.getChatMessage().setMsgId(msgId);
                    nettyData.setAction(NettyResultType.AcceptGroupChatMsg);
                    channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
                } else {
                    userService.saveGroupMsg(nettyData.getChatMessage(), MsgSignFlagEnum.unsign.type, userId);
                    rabbitMqProvider.sendMessage(userId, userId + ",0");
                }
            }
        });
    }

    // 发送群聊图片
    @SocketMapping(NettyRequestType.GroupChatSendImage)
    public void groupChatSendImage(NettyData nettyData, ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("发送群聊图片");
        String extend = nettyData.getExtend();
        String[] allGroupId = extend.split(",");
        ChannelGroup users = ChatInboundHandler.users;

        ctx.channel().eventLoop().execute(() -> {
            for (String userId : allGroupId) {
                Channel channel = SessionFactory.getSession().getChannel(userId);
                if (channel != null && users.find(channel.id()) != null) {
                    String msgId = userService.saveGroupMsg(nettyData.getChatMessage(), MsgSignFlagEnum.signed.type, userId);
                    nettyData.getChatMessage().setMsgId(msgId);
                    nettyData.setAction(NettyResultType.AcceptGroupChatImage);
                    channel.writeAndFlush(new TextWebSocketFrame(JsonUtils.objectToJson(nettyData)));
                } else {
                    userService.saveGroupMsg(nettyData.getChatMessage(), MsgSignFlagEnum.unsign.type, userId);
                    rabbitMqProvider.sendMessage(userId, userId + ",0");
                }
            }
        });
    }


    // 签收群聊接收消息
    @SocketMapping(NettyRequestType.GroupSigningMsg)
    public void groupSigningMsg(NettyData socketData, ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("签收群聊接收消息");
    }

    // 批量签收私聊消息, 以逗号分隔消息id
    @SocketMapping(NettyRequestType.SingleSigningMsg)
    public void singleSigningMsg(NettyData socketData, ChannelHandlerContext ctx, TextWebSocketFrame msg) {
        log.info("批量签收私聊消息");
    }
}
